﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using System.Data;
using Com.StellmanGreene.CSVReader;
using System.Globalization;
using nGSO.Utils;

namespace nGSO.Tests
{
    [TestFixture]
    public class DerivateTest
    {
        private double maxdist = 0.05;
        private int minAgentsAtPeak = 3;

        [Test]
        public void HimmblauDerivateTest_J8()
        {
            List<double[]> resultFromGso = new List<double[]>();

            List<double[]> realOptimums = new List<double[]>();
            realOptimums.Add(new double[] { 3,2 });
            realOptimums.Add(new double[] { -3.779, -3.283 });
            realOptimums.Add(new double[] { -2.805, 3.131 });
            realOptimums.Add(new double[] { 3.584, -1.848 });

            XmlSerializer serializer = new XmlSerializer(typeof(SearchSpace));
            MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(TestData.J8));

            SearchSpace space = serializer.Deserialize(stream) as SearchSpace;
            Assert.IsNotNull(space);
            Assert.IsNotNull(space.Agents);


            List<double> distances = new List<double>();

            foreach (Agent agent in space.Agents)
            {
                foreach (var optimum in realOptimums)
                {
                    double distance = agent.GetDistanceTo(optimum, 2);

                    if (distance < maxdist)
                    {
                        resultFromGso.Add(agent.Loc);
                        distances.Add(distance);

                        continue;
                    }
                }
            }

            Console.WriteLine("Avg distance " + distances.Average());
            Console.WriteLine("Agents in distance " + resultFromGso.Count + " from " + space.Agents.Count);
        }

        [Test]
        public void Rastergin_J2()
        {
            CSVReader csvReader = new CSVReader(TestData.rastergin_optima);
            DataTable optima = csvReader.CreateDataTable(false);
            Assert.IsTrue(optima.Rows.Count == 100);
            List<double[]> realOptimums = new List<double[]>();

            Dictionary<double[], List<double[]>> realOptimaWithAgentLocs = new Dictionary<double[], List<double[]>>();

            for (int i = 0; i < optima.Rows.Count; i++)
            {
                DataRow row = optima.Rows[i];
                
                double x = double.Parse( row.ItemArray[0].ToString().Replace('.',',') );
                double y = double.Parse(row.ItemArray[1].ToString().Replace('.', ','));

                realOptimaWithAgentLocs.Add(new double[] { x, y }, new List<double[]>());
            }


            XmlSerializer serializer = new XmlSerializer(typeof(SearchSpace));
            MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(TestData.J2));
            SearchSpace space = serializer.Deserialize(stream) as SearchSpace;

            List<double> distances = new List<double>();

            foreach (Agent agent in space.Agents)
            {
                foreach (var optimum in realOptimaWithAgentLocs.Keys)
                {
                    double distance = agent.GetDistanceTo(optimum, 2);

                    if (distance < maxdist)
                    {
                        realOptimaWithAgentLocs[optimum].Add(agent.Loc);
                        continue;
                    }
                }
            }

            Console.WriteLine(realOptimaWithAgentLocs.Where(s => s.Value.Count > minAgentsAtPeak).Count());
            //Console.WriteLine("Avg distance " + distances.Average());
            //Console.WriteLine("Agents in distance " + distances.Count + " from " + space.Agents.Count);
        }

        [Test]
        public void DoubleTest()
        {
            OptimumCsvProvider provider = new OptimumCsvProvider();
            Dictionary<double[], List<double[]>> t = new Dictionary<double[],List<double[]>>();
            provider.FillFromFile(t, "AgentFunction_Rastrigin_J2.txt");
        }
    }
}
